package com.sicent.operate.common.util;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

import javax.imageio.ImageIO;

import org.springframework.web.context.ContextLoader;
import org.springframework.web.multipart.MultipartFile;


public class UploadUtil {
	
	/**
	 * 默认图片大小不能超过200K
	 */
	public static Long DEFAULT_IMAGE_SIZE = 200L;

	public static String uploadImage(String relativeUploadPath, Integer barId,
			MultipartFile mFile, Long maxSize, Boolean judgeSuffix, List<String> suffixs) throws Exception {
		BufferedImage bufferedImage = ImageIO.read(mFile.getInputStream());
		if (bufferedImage == null) {
			throw  new Exception("上传失败：您上传的不是图片文件！");
		}
		// 设置默认大小
		if (maxSize == null) {
			maxSize = DEFAULT_IMAGE_SIZE;
		}

		// 控制大小
		long size = mFile.getSize() / 1024;
		if (maxSize != null && size > maxSize) {
			throw new Exception("上传失败：上传图片过大");
		}
		String uploadPath = ContextLoader.getCurrentWebApplicationContext().getServletContext().getRealPath(relativeUploadPath);
		String suffix = mFile.getOriginalFilename().substring(mFile.getOriginalFilename().lastIndexOf(".") + 1,mFile.getOriginalFilename().length());
		long timeStamp = System.currentTimeMillis() / 1000;
		String fileName = barId + "_" + timeStamp;
		File saveDirBig = new File(uploadPath);
		if (!saveDirBig.exists()) {
			saveDirBig.mkdirs();
		}
		File saveDirSmall = new File(uploadPath + "/small/");
		if (!saveDirSmall.exists()) {
			saveDirSmall.mkdirs();
		}
		File dstFileBig = new File(saveDirBig, fileName + "." + suffix);
		ImageUtil.scale(mFile.getInputStream(), dstFileBig, 1, suffix);
		ImageUtil.generateSmall(mFile.getInputStream(),fileName + "." + suffix, uploadPath + "/small/");
		if (judgeSuffix) {
			Boolean haveThis = false;
			if (suffixs != null) {
				if (suffixs.contains(suffix.toLowerCase())) {
					haveThis = true;
				}
			}
			if (!haveThis) {
				throw new Exception("上传失败：该文件格式不能上传");
			}
		}
		return fileName + "." + suffix;
	}
	
	public static String uploadImage(String relativeUploadPath, Integer barId, MultipartFile mFile) throws Exception {
		BufferedImage bufferedImage = ImageIO.read(mFile.getInputStream()); 
		if (bufferedImage == null) {
			throw new Exception("上传失败：您上传的不是图片文件！");
		}
		/*if (width < 512 || height < 512 || size > 5 * 1024 * 1024) {
			throw new BarPictureTooSmallException("上传失败：上传图片的分辨率必须大于512×512且大小小于5M！");
		}*/
		String uploadPath = ContextLoader.getCurrentWebApplicationContext().getServletContext().getRealPath(relativeUploadPath);
		String suffix = mFile.getOriginalFilename().substring(mFile.getOriginalFilename().lastIndexOf(".") + 1, mFile.getOriginalFilename().length());
		long timeStamp = System.currentTimeMillis() / 1000;
		String fileName = barId + "_" + timeStamp;
		File saveDirBig = new File(uploadPath);
		if (!saveDirBig.exists()) {
			saveDirBig.mkdirs();
		}
		File saveDirSmall = new File(uploadPath + "/small/");
		if (!saveDirSmall.exists()) {
			saveDirSmall.mkdirs();
		}
		File dstFileBig = new File(saveDirBig, fileName + "." + suffix);
		scale(mFile.getInputStream(), dstFileBig, 1, suffix);
		generateSmall(mFile.getInputStream(), fileName + "." + suffix, uploadPath + "/small/");
		return fileName + "." + suffix;
	}
	
	public static void zoom(InputStream srcInputStreamImage, File destImageFile, int width, int height, String imageFormat) throws IOException {
		ImageIO.write(zoom(ImageIO.read(srcInputStreamImage), width, height),imageFormat, destImageFile);
	}
	
	private static BufferedImage zoom(BufferedImage srcBufferedImage, int width, int height) {
		int imgWidth = srcBufferedImage.getWidth();
		int imgHeight = srcBufferedImage.getHeight();
		if (imgWidth > width || imgHeight > height) {
			if (Double.valueOf(imgHeight) / imgWidth >= Double.valueOf(height) / width) {
				imgWidth = (int) Math.round(Double.valueOf(height) / imgHeight * imgWidth);
				imgHeight = height;
			} else {
				imgHeight = (int) Math.round(Double.valueOf(width) / imgWidth * imgHeight);
				imgWidth = width;
			}
		}
		BufferedImage destBufferedImage = new BufferedImage(width, height, srcBufferedImage.getType());
		Graphics2D g = destBufferedImage.createGraphics();
		g.setBackground(Color.WHITE);
		g.clearRect(0, 0, width, height);
		g.drawImage(srcBufferedImage.getScaledInstance(imgWidth, imgHeight, Image.SCALE_SMOOTH), 0, 0, width, height, null);
		g.dispose();
		return destBufferedImage;
	}
	
	private final static void scale(InputStream srcInputStreamImage,
			File destImageFile, double scale, String imageFormat)
			throws IOException {
		ImageIO.write(scale(srcInputStreamImage, scale), imageFormat,
				destImageFile);
	}
	
	private final static BufferedImage scale(InputStream srcInputStreamImage,
			double scale) throws IOException {
		return scale(ImageIO.read(srcInputStreamImage), scale);
	}
	
	private final static BufferedImage scale(BufferedImage srcBufferedImage,
			double scale) {
		int width = (int) Math.round(srcBufferedImage.getWidth() * scale);
		int height = (int) Math.round(srcBufferedImage.getHeight() * scale);
		Image image = srcBufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
		BufferedImage destBufferedImage = new BufferedImage(width, height, srcBufferedImage.getType());
		Graphics graphics = destBufferedImage.getGraphics();
		graphics.drawImage(image, 0, 0, null);
		graphics.dispose();
		return destBufferedImage;
	}
	
	private final static void generateSmall(InputStream inputStream, String fileName, String parentPath) throws IOException{
		double totalScale = inputStream.available()/(50*1024.0);
		BufferedImage bufferedImage = ImageIO.read(inputStream);
		int width = bufferedImage.getWidth();
		int height = bufferedImage.getHeight();
		width = (int)(width/Math.sqrt(totalScale));
		height = (int)(height/Math.sqrt(totalScale));
		File smallfile = new File(parentPath + File.separator + fileName);
		if (!smallfile.exists()){
			smallfile.createNewFile();
		}
		Image image = bufferedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH);
		BufferedImage destBufferedImage = new BufferedImage(width, height, bufferedImage.getType());
		Graphics graphics = destBufferedImage.getGraphics();
		graphics.drawImage(image, 0, 0, null);
		graphics.dispose();
		FileOutputStream out = new FileOutputStream(smallfile);
		ImageIO.write(destBufferedImage, fileName.substring(fileName.lastIndexOf(".") + 1), out);
        out.close();
	}
	
	/*
	 * 上传文件到指定的目录
	 * uplaodFileName:需要被上传的文件，如：C:/test.txt
	 * targetPath:文件上传到目录
	 */
	public static void upload(String uplaodFileName, String targetPath) throws Exception{
		//判断需要上传的文件是否存在
		File uploadFile = new File(uplaodFileName);
		if(!uploadFile.exists()){
			throw new Exception("upload file not exist, fileName=" + uplaodFileName);
		}
		//截取上传文件的名称
		String fileName = uplaodFileName.substring(uplaodFileName.lastIndexOf("/") + 1, uplaodFileName.length());
		
		//判断目标目录是否，不存在则新建
		File targetFolder = new File(targetPath);
		if(!targetFolder.exists()){
			targetFolder.mkdirs();
		}
		//将文件名拼接到目标目录后，形成完整文件路径
		String targetFileName = targetPath  + fileName;
		InputStream is = new FileInputStream(uploadFile);// 把文件读入
		OutputStream os = new FileOutputStream(targetFileName);
		int bytesRead = 0;
		byte[] buffer = new byte[8192];
		while ((bytesRead = is.read(buffer, 0, 8192)) != -1) {
			os.write(buffer, 0, bytesRead);// 将文件写入服务器
		}
		os.close();
		is.close();
	}
}
